iT邦幫忙

1

React Controlled and uncontrolled components 的前世今生

  • 分享至 

  • xImage
  •  

前陣子鐵人賽時有看到 Pjchender 有分享到 React 新舊官網在針對 Controlled and uncontrolled components 有不同的解釋 (文章連結會放在下面),剛好最近有在看 React Beta 所以想說來整理一下

Controlled and uncontrolled components

在 React 新舊官網中,對 controlled, uncontrolled components 有著截然不同的解釋,這邊先直接講結論:

  • 舊官網: 狀態是否能被 React 所控制
  • 新官網: 狀態是否能被 父層 所控制

是否有點好奇了?那我們繼續

舊官網

在官網一開始,就有著斗大的標題

在大多數的情況下,我們推薦使用 controlled component 來實作表單。在控制元件裡,表單的資料是被 React component 所處理。另一個選擇是 uncontrolled component,表單的資料是由 DOM 本身所處理的。

這邊有幾個重點: 這邊的 controlled 或是 uncontrolled component 是針對表單裡面的資料由誰控制所決定

如果不太清楚沒關係,我們直接上程式碼

controlled component

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

上方程式碼取自於 React,我們可以看到 input 的 value 是來自於 React 的 state ,並且在更改狀態時,是使用 this.setState 去更改,以前面的定義:表單的資料是被 React 所處理,所以我們知道這是一個 controlled component

uncontrolled component

一樣直接上程式碼

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.input = React.createRef();
  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.input.current.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" ref={this.input} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

可以看到我們是使用 ref 來從 DOM 取得表單的資料,而不是透過 React 的 state 去做更新

(如果有不太清楚 ref 如何使用的讀者,這邊推一下這篇文章,個人覺得寫得不錯,或是也可看 React beta,寫的也是非常清楚)

以上兩段程式碼,相信各位已經很清楚舊版 controlled 或是 uncontrolled component 的定義了吧

那接下來,請你忘記剛剛所看到的,因為我們即將了解新版的定義


新官網(React Beta)

在新官網中,我們對於 Controlled, uncontrolled components 的定義是: state 是否能被 父層 所控制

聰明的你,是否覺得覺得怪怪的?state 被父層控制?那不就是 props?沒錯,簡單來說就是 props ,那到底一個 Component 是 controlled 的,還是 uncontrolled 的?

each component usually has some mix of both local state and props. However, this is a useful way to talk about how components are designed and what capabilities they offer.

這邊有提到,一個 Component 裡面可能會包含 controlled, uncontrolled 的狀態,我們應該專注於他們所做的事情上面

所以 controlled , uncontrolled 該如何選擇?

Uncontrolled components are easier to use within their parents because they require less configuration. But they're less flexible when you want to coordinate them together. Controlled components are maximally flexible, but they require the parent components to fully configure them with props.

簡單來說就是 Uncontrolled components 相對起來更為容易書寫,因為他少了些配置,不過當狀態需要跟別人共享時,就會顯得更為困難

反觀 Controlled components 會需要設定比較多東西,不過卻也相對比較靈活

這邊所說需要的配置像是: props, prop-types …


結論

這邊筆者個人更為喜歡舊版的解釋,並且也更接受舊版的解釋,新版的部分覺得沒有那麼必要,甚至感覺有點多餘了,不過如果在面試時,能說出這兩種版本差異,應該會蠻加分的,那沒有問題的話,我們就下次見,拜拜

有任何錯誤,或是問題都歡迎留言給我,謝謝
文章同步分享到 Medium 有興趣的讀者可以去看看

參考文章:
https://zh-hant.reactjs.org/docs/forms.html#controlled-components
https://zh-hant.reactjs.org/docs/uncontrolled-components.html
https://beta.reactjs.org/learn/sharing-state-between-components#step-3-add-state-to-the-common-parent
https://ithelp.ithome.com.tw/articles/10297168


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言